package com.xyzwps.server.paimon.it

import com.xyzwps.server.paimon.app.dto.Me
import com.xyzwps.server.paimon.common.Utils
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.*
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.web.server.LocalServerPort

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class GqlRegisterAndLoginTests(@LocalServerPort port: Int) : GqlTestBase(port) {

    @Test
    fun registerAndLoginTest() {
        graphQlTester.document("{ me { id nickname createdAt token } }")
            .execute()
            .errors()
            .satisfy { errors ->
                assertEquals(1, errors.size)
                val error = errors.first()
                assertEquals("UNAUTHORIZED", error.extensions?.get("title"))
                assertEquals("/errors/100", error.extensions?.get("type"))
                assertEquals(401, error.extensions?.get("status"))
            }

        val phone = UiTestHelper.genPhone()
        val registerDkey = graphQlTester.document("mutation { registerSendVcode(input: { phone: \"$phone\" }) } ")
            .execute()
            .path("registerSendVcode")
            .entity(String::class.java)
            .get()

        graphQlTester.document("mutation { register(input: { phone: \"$phone\", vcode: \"666666\", dkey: \"$registerDkey\" }) } ")
            .execute()
            .path("register")
            .valueIsNull()

        val loginDkey = graphQlTester.document("mutation { loginSendVcode(input: { phone: \"$phone\" }) } ")
            .execute()
            .path("loginSendVcode")
            .entity(String::class.java)
            .get()

        val me = graphQlTester.document("mutation { login(input: { phone: \"$phone\", vcode: \"666666\", dkey: \"$loginDkey\" }) { id nickname createdAt token } } ")
            .execute()
            .path("login")
            .entity(Me::class.java)
            .get()
        assertNotNull(me.id)
        assertEquals(Utils.maskPhone(phone), me.nickname)
        assertNotNull(me.createdAt)

        val token = me.token
        assertNotNull(token)
        token!!

        graphQlTester.mutate()
            .headers { headers -> headers.setBearerAuth(token) }
            .build()
            .document("{ me { id nickname createdAt token } }")
            .execute()
            .path("me")
            .entity(Me::class.java)
            .satisfies { x ->
                assertEquals(me.id, x.id)
                assertEquals(me.nickname, x.nickname)
                assertEquals(me.createdAt, x.createdAt)
                assertNull(x.token)
            }
    }
}
